/* 
 *  Copyright (C) 2009-2010 milkyjing <milkyjing@gmail.com>
 *
 *  This Program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *   
 *  This Program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *   
 *  You should have received a copy of the GNU General Public License
 *  along with GNU Make; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
 *  http://www.gnu.org/copyleft/gpl.html
 *
 */

#ifndef TCXLIB_PIX_H
#define TCXLIB_PIX_H
#pragma once

#include "std.h"


#define MATH_PI 3.14159265358979323846264338327950288

#define MAKE8B8B8B(r,g,b) ((unsigned long)((unsigned char)(r) | ((unsigned short)((unsigned char)(g)) << 8) | ((unsigned long)((unsigned char)(b)) << 16)))
#define MAKERGB MAKE8B8B8B


/**
 * TCX_Pix structure used to store pixel info of text(s) / image(s).
 */
typedef struct _tcx_pix {
    double initX;    /**< left most */
    double initY;    /**< upper most */
    int width;     /**< width of the PIX */
    int height;    /**< height of the PIX */
    int size;    /**< size = height * (width * 4) */
    unsigned char *buf;    /**< pixel values of the PIX */
} TCX_Pix, *TCX_pPix;

/**
 * TCX_PyPix structure that has the following structure ((initX, initY), (width, height), (a1, a2, a3, ...)).
 */
typedef PyObject *TCX_PyPix;

/**
 * TCX_PyBigPix structure that has the following structure [(PIX, offset_x, offset_y, layer), (PIX, offset_x, offset_y, layer), ...].
 */
typedef PyObject *TCX_PyBigPix;


/* Inhibit C++ name-mangling for tcxLib functions but not for system calls. */
#ifdef __cplusplus
extern "C" {
#endif    /* __cplusplus */

/**
 * Convert TCX PIX to TCX PY PIX.
 * @param pPix pointer to TCX_Pix structure
 * @param delPix indicates whether to delete PIX before returning of the function
 * @return TCX_PyPix
 */
extern TCX_PyPix tcxlib_convert_pix(const TCX_pPix pPix, int delPix);

/**
 * Convert TCX PY PIX to TCX PIX. 
 * Remark: in the following functions we will just use PIX, it may stand for TCX PIX or TCX PY PIX, in case that there is no ambiguity.
 *
 * @param pyPix the TCX_PyPix structure
 * @param pPix pointer to TCX_Pix structure that is going to hold the converted data
 * @return const TCX_pPix
 */
extern const TCX_pPix tcxlib_convert_py_pix(const TCX_PyPix pyPix, TCX_pPix pPix);

/**
 * Create a blank PIX.
 * @param self reserved
 * @param args (width, height, rgba)
 * @return TCX_PyPix
 */
extern TCX_PyPix tcxlib_create_blank_pix(PyObject *self, PyObject *args);

/**
 * Resample TCX PIX. 
 * Remark: the target width and height should be specified in the target TCX_Pix structure before it is sent to the function. 
 * Other variables will be ignored. Note that the `buf' of the target TCX_Pix structure should be empty before it is sent to the function, 
 * otherwise will cause memory leaking.
 *
 * @param pPixSrc pointer to source TCX_Pix structure
 * @param pPixDst pointer to target TCX_Pix structure
 * @return TCX_pPix
 */
extern const TCX_pPix tcxlib_resample_pix(const TCX_pPix pPixSrc, TCX_pPix pPixDst);

/**
 * Resample TCX PY PIX.
 * @param self reserved
 * @param args (PIX, width, height)
 * @return TCX_PyPix
 */
extern TCX_PyPix tcxlib_resample_py_pix(PyObject *self, PyObject *args);

/**
 * Applay a texture to PIX.
 * @param self reserved
 * @param args (PIX, Texture)
 * @return TCX_PyPix
 */
extern TCX_PyPix tcxlib_apply_pix_texture(PyObject *self, PyObject *args);

/**
 * Applay a mask to PIX.
 * @param self reserved
 * @param args (PIX, Mask)
 * @return TCX_PyPix
 */
extern TCX_PyPix tcxlib_apply_pix_mask(PyObject *self, PyObject *args);

/**
 * Enlarge a PIX. 
 * Remark: the PIX is put in the middle of the enlarged one, and the extra space is filled with 0. 
 * The target width and height should be specified in the target TCX_Pix structure before it is sent to the function. 
 * And target width and height should be both larger than (or equal to) source ones. 
 * Other variables will be ignored. Note that the `buf' of the target TCX_Pix structure should be empty before it is sent to the function, 
 * otherwise will cause memory leaking.
 *
 * @param pPixSrc pointer to source TCX_Pix structure
 * @param pPixDst pointer to target TCX_Pix structure
 * @return TCX_pPix
 */
extern const TCX_pPix tcxlib_enlarge_pix(const TCX_pPix pPixSrc, TCX_pPix pPixDst);

/**
 * Enlarge a TCX PY PIX.
 * @param self reserved
 * @param args (PIX, x, y)
 * @return TCX_PyPix
 */
extern TCX_PyPix tcxlib_enlarge_py_pix(PyObject *self, PyObject *args);

/**
 * Crop a TCX PY PIX.
 * @param self reserved
 * @param args (PIX, left, top, right, bottom)
 * @return TCX_PyPix
 */
extern TCX_PyPix tcxlib_crop_py_pix(PyObject *self, PyObject *args);

/**
 * Applay Gauss IIR blur to a PIX.
 * @param self reserved
 * @param args (PIX, radius)
 * @return TCX_PyPix
 */
extern TCX_PyPix tcxlib_apply_gauss_blur(PyObject *self, PyObject *args);

/**
 * Combine two PIXs, i.e., overlay one PIX upon the other.
 * @param self reserved
 * @param args (back, overlay)
 * @return TCX_PyPix
 */
extern TCX_PyPix tcxlib_combine_two_pixs(PyObject *self, PyObject *args);

/**
 * Change the color of a PIX by multiplying factors to each channel of RGBA.
 * @param self reserved
 * @param args (PIX, r_f, g_f, b_f, a_f)
 * @return TCX_PyPix
 */
extern TCX_PyPix tcxlib_pix_color_multiply(PyObject *self, PyObject *args);

/**
 * Change the color of a PIX by shifting values of each channel of RGBA.
 * @param self reserved
 * @param args (PIX, r, g, b, a)
 * @return TCX_PyPix
 */
extern TCX_PyPix tcxlib_pix_color_shift(PyObject *self, PyObject *args);

/**
 * Make the color in a PIX with specified rgb value transparent.
 * @param self reserved
 * @param args (PIX, rgb)
 * @return TCX_PyPix
 */
extern TCX_PyPix tcxlib_pix_color_transparent(PyObject *self, PyObject *args);

/**
 * Change the value of colors including alpha channels in the PIX with flat rgba value.
 * @param self reserved
 * @param args (PIX, rgba)
 * @return TCX_PyPix
 */
extern TCX_PyPix tcxlib_pix_color_flat_rgba(PyObject *self, PyObject *args);

/**
 * Change the value of colors in the PIX with flat rgb value.
 * @param self reserved
 * @param args (PIX, rgb)
 * @return TCX_PyPix
 */
extern TCX_PyPix tcxlib_pix_color_flat_rgb(PyObject *self, PyObject *args);

/**
 * Change the value of alpha channels in the PIX with constant alpha value.
 * @param self reserved
 * @param args (PIX, alpha)
 * @return TCX_PyPix
 */
extern TCX_PyPix tcxlib_pix_color_flat_alpha(PyObject *self, PyObject *args);

/**
 * Bilinear filter, mainly used in moving a PIX, so that it will look smoother. 
 * Remark: this function is for internal use, it is used to manipulate a TCX PIX.
 *
 * @see tcxlib_bilinear_filter()
 * @param pPixSrc pointer to the source TCX_Pix structure
 * @param offset_x offset of the PIX in the horizontal direction
 * @param offset_y offset of the PIX in the vertical direction
 * @param pPixDst pointer to the target TCX_Pix structure
 * @return const TCX_pPix
 */
extern const TCX_pPix tcxlib_bilinear_filter_internal(const TCX_pPix pPixSrc, double offset_x, double offset_y, TCX_pPix pPixDst);

/**
 * Bilinear filter, mainly used in moving a PIX, so that it will look smoother.
 * @see tcxlib_bilinear_filter_internal()
 * @param self reserved
 * @param args (PIX, offset_x, offset_y)
 * @return TCX_PyPix
 */
extern TCX_PyPix tcxlib_bilinear_filter(PyObject *self, PyObject *args);

/**
 * Create a TCX PY BIG PIX structure.
 * @param self reserved
 * @param args ()
 * @return TCX_PyBigPix
 */
extern TCX_PyBigPix tcxlib_init_big_pix(PyObject *self, PyObject *args);

/**
 * Add a PIX to BigPIX.
 * @param self reserved
 * @param args (BIG_PIX, PIX, offset_x, offset_y, layer)
 * @return TCX_Py_Error_Code
 */
extern TCX_Py_Error_Code tcxlib_big_pix_add(PyObject *self, PyObject *args);

/**
 * Convert BigPIX to PIX.
 * @param self reserved
 * @param args (BIG_PIX)
 * @return TCX_PyPix
 */
extern TCX_PyPix tcxlib_convert_big_pix(PyObject *self, PyObject *args);

#ifdef __cplusplus
}
#endif    /* __cplusplus */

#endif    /* TCXLIB_PIX_H */

